package Model;
import java.util.*;

public class AddSubTaskCommand implements Command
{
   //attributes
   private ArrayList<Task> TasksPointer;
   @SuppressWarnings("unused")
   private ArrayList<Task> SubTasksPointer;
   private Task NewSubTask;
   private boolean undone;
   private Task AddedParentTask;

    //-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

 
	public AddSubTaskCommand(ArrayList<Task> PointerToTasks)
	{
		TasksPointer=PointerToTasks;
        undone=false;
	}

    //-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

    public void execute(String parentTask, String taskName, String iPeriodic, String periodicFrequency, Date iDate) throws Exception //iPeriodic should be either "Single" OR "Periodic"
    {                                                                                                   //periodicFrequency should be either Daily, Weekly or Monthly or null
        boolean wError = false;
        boolean cError = false;
        
    	if(parentTask != null)
		{
			for(int i = 0; i < TasksPointer.size(); ++i)
			{
				Iterator<Task> iteratesThroughParentTaskOfTree = TasksPointer.get(i).iterator();
				TaskTreeIterator temp;
				temp = (TaskTreeIterator)iteratesThroughParentTaskOfTree;	
				Task currentInTree;
				boolean loopGuard=true;
				
				while(loopGuard) // go through entire Tree in search for ParentTask Name
				{				
					currentInTree = temp.getCurrent();
					
					//if Parent Task is found AND its complex, then we can nest a task under it. 
					if(currentInTree.getName().equals(parentTask) && currentInTree.getType().equals("Complex"))
					{
	                    if(iPeriodic.equals("Single"))
	                    {
	                        SingleTask TemporaryPointer = new SingleTask(taskName,iDate,iPeriodic);
	                        currentInTree.getSubtasks().add(TemporaryPointer);
	                        NewSubTask = TemporaryPointer;
	                        AddedParentTask = currentInTree;
	                        return;
	                    }
	                    else if(iPeriodic.equals("Periodic"))
	                    {
	                        PeriodicTask TemporaryPointer = new PeriodicTask(taskName,TasksPointer.get(i).getDueDate(),iPeriodic,periodicFrequency);
	                        currentInTree.getSubtasks().add(TemporaryPointer);	                        
	                        NewSubTask = TemporaryPointer;
	                        AddedParentTask = currentInTree;
	                        return;
	                    }
	                    
	                    //allows multiple nesting. Complex Tasks Under Complex Tasks.
	                    else if(iPeriodic.equals("Complex"))
	                    {
	                    	ComplexTask TemporaryPointer = new ComplexTask(taskName,TasksPointer.get(i).getDueDate(),iPeriodic);
	                    	currentInTree.getSubtasks().add(TemporaryPointer);	  
	                    	NewSubTask = TemporaryPointer;
	                    	AddedParentTask = currentInTree;
	                    	return;
	                    }
					}
					
					else if(currentInTree.getName().equals(parentTask) && currentInTree.getType().equals("Complex")==false)
					{
						cError=true;
					}
					
					if(iteratesThroughParentTaskOfTree.hasNext())
					{
						iteratesThroughParentTaskOfTree.next();
					}
					
					else if(iteratesThroughParentTaskOfTree.hasNext()==false)
					{
						loopGuard = false;
					}	
				}//end of while-loop
			}//end of for-loop
			
			wError=true;
		}//end of outer-if
    	
    	if(cError)
    	{
    		throw new Exception("Cannot add Sub-Task to a Non-Complex Task.");
    	}
    	
    	if(wError)
    	{
    		throw new Exception("No Sub-Task Was added !");
    	}
    }

    //-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

    public void undo()
    {
        if(AddedParentTask != null && !undone && AddedParentTask !=null)
		{
        	ComplexTask tempPointer = (ComplexTask)AddedParentTask;
            tempPointer.removeTask(NewSubTask); //removeTask removes based on Memory Reference Addresse.
            undone=true;
        }
    }

    //-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------

    public void redo()
    {
        if(AddedParentTask != null && undone && AddedParentTask !=null)
		{
        	ComplexTask tempPointer = (ComplexTask)AddedParentTask;
            tempPointer.addTodoItem(NewSubTask);
            undone=false;
        }
    }

    //-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------
	//-----------------------------------------------------------------------------------
}
